<template>
  <div class="form-select">
    <!-- 标签 -->
    <div v-if="label" class="select-label">
      <span class="label-text">{{ label }}</span>
      <span v-if="required" class="required-mark">*</span>
      <el-tooltip v-if="tooltip" :content="tooltip" placement="top">
        <el-icon class="tooltip-icon"><QuestionFilled /></el-icon>
      </el-tooltip>
    </div>

    <!-- 选择器 -->
    <div class="select-wrapper" :class="{ 'has-error': hasError }">
      <el-select
        v-model="selectValue"
        v-bind="$attrs"
        :placeholder="placeholder"
        :multiple="multiple"
        :disabled="disabled"
        :clearable="clearable"
        :collapse-tags="collapseTags"
        :collapse-tags-tooltip="collapseTagsTooltip"
        :max-collapse-tags="maxCollapseTags"
        :multiple-limit="multipleLimit"
        :remote="remote"
        :remote-method="remoteMethod"
        :loading="loading"
        :filterable="filterable"
        :filter-method="filterMethod"
        :allow-create="allowCreate"
        :no-data-text="noDataText"
        :no-match-text="noMatchText"
        :teleported="teleported"
        :persistent="persistent"
        :size="size"
        @change="handleChange"
        @visible-change="handleVisibleChange"
        @remove-tag="handleRemoveTag"
        @clear="handleClear"
        @blur="handleBlur"
        @focus="handleFocus"
      >
        <!-- 选项组 -->
        <template v-if="groups && groups.length">
          <el-option-group
            v-for="group in groups"
            :key="group.label"
            :label="group.label"
          >
            <el-option
              v-for="item in group.options"
              :key="item.value"
              :label="item.label"
              :value="item.value"
              :disabled="item.disabled"
            >
              <!-- 自定义选项内容 -->
              <slot name="option" :item="item" v-if="$slots.option">
                {{ item.label }}
              </slot>
            </el-option>
          </el-option-group>
        </template>

        <!-- 普通选项 -->
        <template v-else>
          <el-option
            v-for="item in options"
            :key="item.value"
            :label="item.label"
            :value="item.value"
            :disabled="item.disabled"
          >
            <!-- 自定义选项内容 -->
            <slot name="option" :item="item" v-if="$slots.option">
              {{ item.label }}
            </slot>
          </el-option>
        </template>

        <!-- 前缀图标 -->
        <template v-if="prefixIcon" #prefix>
          <el-icon><component :is="prefixIcon" /></el-icon>
        </template>

        <!-- 空状态 -->
        <template v-if="$slots.empty" #empty>
          <slot name="empty" />
        </template>
      </el-select>

      <!-- 验证错误信息 -->
      <div v-if="hasError" class="error-message">
        {{ errorMessage }}
      </div>

      <!-- 帮助文本 -->
      <div v-if="helpText && !hasError" class="help-text">
        {{ helpText }}
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed } from "vue";
import { QuestionFilled } from "@element-plus/icons-vue";

const props = defineProps({
  modelValue: {
    type: [String, Number, Array],
    default: "",
  },
  label: {
    type: String,
    default: "",
  },
  placeholder: {
    type: String,
    default: "请选择",
  },
  options: {
    type: Array,
    default: () => [],
  },
  groups: {
    type: Array,
    default: () => [],
  },
  multiple: {
    type: Boolean,
    default: false,
  },
  disabled: {
    type: Boolean,
    default: false,
  },
  clearable: {
    type: Boolean,
    default: true,
  },
  collapseTags: {
    type: Boolean,
    default: false,
  },
  collapseTagsTooltip: {
    type: Boolean,
    default: false,
  },
  maxCollapseTags: {
    type: Number,
    default: 1,
  },
  multipleLimit: {
    type: Number,
    default: 0,
  },
  remote: {
    type: Boolean,
    default: false,
  },
  loading: {
    type: Boolean,
    default: false,
  },
  filterable: {
    type: Boolean,
    default: false,
  },
  allowCreate: {
    type: Boolean,
    default: false,
  },
  noDataText: {
    type: String,
    default: "暂无数据",
  },
  noMatchText: {
    type: String,
    default: "无匹配数据",
  },
  teleported: {
    type: Boolean,
    default: true,
  },
  persistent: {
    type: Boolean,
    default: true,
  },
  size: {
    type: String,
    default: "default",
    validator: (value) => ["large", "default", "small"].includes(value),
  },
  required: {
    type: Boolean,
    default: false,
  },
  prefixIcon: {
    type: [String, Object],
    default: "",
  },
  tooltip: {
    type: String,
    default: "",
  },
  helpText: {
    type: String,
    default: "",
  },
  rules: {
    type: Array,
    default: () => [],
  },
});

const emit = defineEmits([
  "update:modelValue",
  "change",
  "visible-change",
  "remove-tag",
  "clear",
  "blur",
  "focus",
  "error",
  "valid",
]);

const selectValue = computed({
  get: () => props.modelValue,
  set: (value) => emit("update:modelValue", value),
});

const errorMessage = ref("");
const hasError = computed(() => !!errorMessage.value);

// 验证选择值
const validate = (value) => {
  if (!props.rules.length) return true;

  for (const rule of props.rules) {
    if (rule.required) {
      const isEmpty = Array.isArray(value) ? value.length === 0 : !value;
      if (isEmpty) {
        errorMessage.value = rule.message || "此项为必选项";
        return false;
      }
    }

    if (rule.validator) {
      try {
        const result = rule.validator(value);
        if (result !== true) {
          errorMessage.value = result || "验证失败";
          return false;
        }
      } catch (error) {
        errorMessage.value = error.message || "验证失败";
        return false;
      }
    }
  }

  errorMessage.value = "";
  return true;
};

// 处理选择变更
const handleChange = (value) => {
  const isValid = validate(value);
  emit("change", value);
  emit(isValid ? "valid" : "error", errorMessage.value);
};

// 处理可见性变更
const handleVisibleChange = (visible) => {
  emit("visible-change", visible);
};

// 处理标签移除
const handleRemoveTag = (tag) => {
  emit("remove-tag", tag);
};

// 处理清空
const handleClear = () => {
  emit("clear");
};

// 处理失焦
const handleBlur = (event) => {
  emit("blur", event);
};

// 处理聚焦
const handleFocus = (event) => {
  emit("focus", event);
};

// 远程搜索方法
const remoteMethod = (query) => {
  if (props.remote && typeof props.$attrs["remote-method"] === "function") {
    props.$attrs["remote-method"](query);
  }
};

// 本地过滤方法
const filterMethod = (query) => {
  if (props.filterable && typeof props.$attrs["filter-method"] === "function") {
    props.$attrs["filter-method"](query);
  }
};
</script>

<style lang="scss" scoped>
.form-select {
  @apply mb-4;

  .select-label {
    @apply flex items-center mb-1;

    .label-text {
      @apply text-sm text-gray-700 font-medium;
    }

    .required-mark {
      @apply text-red-500 ml-1;
    }

    .tooltip-icon {
      @apply ml-1 text-gray-400 cursor-help;
    }
  }

  .select-wrapper {
    @apply relative;

    :deep(.el-select) {
      @apply w-full;
    }

    &.has-error {
      :deep(.el-input__wrapper) {
        @apply border-red-500 hover:border-red-500 focus:border-red-500;
        box-shadow: 0 0 0 1px var(--el-color-danger) inset;
      }
    }

    .error-message {
      @apply mt-1 text-sm text-red-500;
    }

    .help-text {
      @apply mt-1 text-sm text-gray-500;
    }
  }
}
</style>
